/*  File Name	: Service.h
 *  Author		: Javie Pong
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2011-9-1
 *  Description:
 */

#ifndef SERVICE_H_
#define SERVICE_H_
#include "SvcHandler.h"
#include "Monitor.h"
#include "MakeMsgBlock.h"

class Service: public SvcHandler
{
public:
	Service(int p=0);

	virtual ~Service();

	virtual int open(void * =0);

	virtual int handle_input(int fd = INVALID_HANDLER);

	virtual int handle_output(int fd = INVALID_HANDLER);

	virtual int handle_timeout(void);

	virtual int handle_close(int handle = INVALID_HANDLER,
			ReactorMask = EventHandler::ALL_MASK);

	virtual int recv_msg(MessageBlock *mb,const int size,int flag=MSG_NOSIGNAL);

	virtual int send_msg(MessageBlock *mb,int len,int flag=0);

	virtual int make_block(MessageBlock *mb,int len);

	virtual int get_block(MessageBlock *mb);

	virtual void reset(void);

	virtual std::string name(void);

	virtual int start_timer(TimeValue delay,TimeValue interval);

	virtual int stop_timer(void);

	long timer_id(void);

	int unique_id(void);

	void set_unique_id(int id);

	const char *peer_addr(void);

	const int peer_port(void);

protected:
	RT_MUTEX read_lock_;

	char conn_addr_[64];
	int port_;
	unsigned int unique_id_;
	int recv_msg_count_;
	long timer_id_;
	long last_recv_msg_;

	MakeMsgBlock msg_block_;

private:
	typedef SvcHandler super;
};

template<class MONITOR>
class ServiceEX:public Service
{
public:
	ServiceEX();
	virtual ~ServiceEX();
	MONITOR* monitor(MONITOR *monitor=NULL);

	virtual int make_block(MessageBlock *mb,int len);
private:
	MONITOR *monitor_;
};

template<class MONITOR>
ServiceEX<MONITOR>::ServiceEX()
{
	this->monitor_ = NULL;
}

template<class MONITOR>
ServiceEX<MONITOR>::~ServiceEX()
{

}

template<class MONITOR>
MONITOR* ServiceEX<MONITOR>::monitor(MONITOR *monitor)
{
	if(NULL!=monitor)
	{
		this->monitor_ = monitor;
	}
	return this->monitor_;
}

template<class MONITOR>
int ServiceEX<MONITOR>::make_block(MessageBlock *mb,int len)
{
	int ret =Service::make_block(mb,len);
	this->monitor()->msg_pool()->push(mb);
	return ret;
}

#endif /* SERVICE_H_ */
